theme_custom <- function(legend.position = "bottom", 
                         plot.title.size = 1.4,
                         axis.title.x.margin = 10,
                         base_size = 13){
  theme_minimal(base_size = base_size) %+replace%
    theme(
      legend.position = legend.position,
      panel.grid.minor = element_blank(),
      plot.title = element_text(face = "bold", size = rel(plot.title.size)),
      plot.subtitle = element_text(face = "plain", size = rel(1.3)),
      plot.caption = element_text(color = "darkgrey", hjust = 1,
                                  face = "italic", size = 10),
      axis.title = element_text(face = "bold"),
      axis.title.x = element_text(margin = margin(t = axis.title.x.margin), hjust = 0),
      axis.title.y = element_text(margin = margin(r = 10), hjust = 1, angle = 90),
      strip.text = element_text(face = "bold", size = rel(1.2))
    )
}

# performance battery
rename_perf <- function(old_name) {
  recode(old_name, 
         perf_ban_ideology = "All parties allowed",
         perf_candidates_disclose = "Candidates disclose info",
         perf_common_und = "Common understanding of facts",
         perf_compromise = "Compromise sought",
         perf_contributions = "Contribs not determine policy",
         perf_districts = "Districts not biased",
         perf_election_fraud = "Fraud-free elections",
         perf_equal_rights = "Equal political/legal rights",
         perf_expand_executive = "Constitution limits executive",
         perf_foreign = "No foreign influence",
         perf_foreign_influence = "No foreign influence",
         perf_free_speech = "Free speech",
         perf_funds_transparent = "Campaign funds transparent",
         perf_gov_stats = "Gov stats are not influenced",
         perf_investigations = "Investigations not compromised",
         perf_journalists = "No interference with press",
         perf_judicial_ind = "Judicial independence",
         perf_judiciary_check = "Judiciary can limit executive",
         perf_legislature_check = "Legislature can limit executive",
         perf_misconduct = "Sanctions for misconduct",
         perf_monitor_opponents = "Agencies do not punish",
         perf_opinions = "Opinions heard on policy",
         perf_participation = "Participation high",
         perf_patriotism = "Patriotism not questioned",
         perf_private_gain = "No private gains from office",
         perf_private_violence = "No political violence",
         perf_protest = "Protest tolerated",
         perf_votes_impact = "Votes have equal impact",
         perf_voting_rights = "Equal voting rights",
         perf_concede_defeat = "Concedes defeat",
         perf_equal_enforce = "Law applies equally")
}

# wave to date
date_me_fxn <- function (data) {
  require(lubridate)
  
  data %>% 
    mutate(
      date = case_when(
        wave == 1 ~ mdy("2/13/2017"),
        wave == 2 ~ mdy("5/11/2017"),
        wave == 3 ~ mdy("9/9/2017"),
        wave == 4 ~ mdy("1/20/2018"),
        wave == 5 ~ mdy("4/9/2018"),
        wave == 6 ~ mdy("7/12/2018"),
        wave == 7 ~ mdy("10/24/2018"),
        wave == 8 ~ mdy("3/15/2019"),
        wave == 9 ~ mdy("10/15/2019"),
        wave == 10 ~ mdy("3/15/2020"),
        wave == 11 ~ mdy("8/12/2020"),
        wave == 12 ~ mdy("10/16/2020"),
        wave == 13 ~ mdy("11/20/2020"),
        wave == 14 ~ mdy("2/2/2021"),
        wave == 15 ~ mdy("6/28/2021"),
        wave == 16 ~ mdy("11/19/2021"),
        wave == 17 ~ mdy("10/14/2022"),
        wave == 18 ~ mdy("11/30/2022"),
        wave == 19 ~ mdy("07/11/2023") # use survey end date
      )
    )
}

mean_and_ci = function(data, outcome, by = "NULL", survey_weight = "NULL"){
  if(survey_weight == "NULL"){
    if(by == "NULL"){
      data %>% 
        summarise(
          mean = mean(eval(parse(text=outcome)), na.rm = T),
          n = sum(!is.na(eval(parse(text=outcome)))),
          ci_l = mean - qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                 na.rm = T) / n)),
          ci_u = mean + qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                 na.rm = T) / n))
          
          
        )
    }else{
      if(str_detect(by, "\\+")){
        by_split = str_split(by, "\\+")[[1]]
        if(length(by_split) == 2){
          data = data %>% 
            group_by(eval(parse(text=by_split[1])), eval(parse(text=by_split[2])))
        }else if(length(by_split) == 3){
          data = data %>% 
            group_by(eval(parse(text=by_split[1])), 
                     eval(parse(text=by_split[2])),
                     eval(parse(text=by_split[3])))
        }
        
        data = data %>% 
          summarise(
            mean = mean(eval(parse(text=outcome)), na.rm = T),
            n = sum(!is.na(eval(parse(text=outcome)))),
            sd = sd(eval(parse(text=outcome)), na.rm = T),
            ci_l = mean - qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                   na.rm = T) / n)),
            ci_u = mean + qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                   na.rm = T) / n))
            
            
          ) %>%
          rename_with(
            .fn = function(x) by_split, 
            .cols = contains("eval(parse")
          )
      }else{
        data %>% 
          group_by(eval(parse(text=by))) %>% 
          summarise(
            mean = mean(eval(parse(text=outcome)), na.rm = T),
            n = sum(!is.na(eval(parse(text=outcome)))),
            sd = sd(eval(parse(text=outcome)), na.rm = T),
            ci_l = mean - qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                   na.rm = T) / n)),
            ci_u = mean + qt(0.975, n) * (sqrt(var(eval(parse(text=outcome)), 
                                                   na.rm = T) / n))
            
            
          ) %>% 
          rename_with(
            .fn = function(x) by, 
            .cols = contains("eval(parse")
          )
      }
    }
  }else if(survey_weight != "NULL"){
    # if the "by" argument contains a "+" sign, then there are 2+ variables
    # by which to group
    if(str_detect(by, "\\+")){
      by_split = str_split(by, "\\+")[[1]]
      if(length(by_split) == 2){
        data = data %>% 
          group_by(eval(parse(text=by_split[1])), eval(parse(text=by_split[2])))
      }else if(length(by_split == 3)){
        data = data %>% 
          group_by(eval(parse(text=by_split[1])), eval(parse(text=by_split[2])),
                   eval(parse(text=by_split[3])))
      }
      data %>% 
        filter(!is.na(eval(parse(text=outcome)))) %>% 
        summarise(
          mean = weighted.mean(x = eval(parse(text=outcome)),
                               w = eval(parse(text=survey_weight)),
                               na.rm = T),
          n_raw = sum(!is.na(eval(parse(text=outcome)))),
          n_weight = sum(eval(parse(text=survey_weight))),
          se = return_se_wgt(eval(parse(text=survey_weight)),
                             eval(parse(text=outcome)),
                             mean),
          ci_l = mean - qt(0.975, n_weight)*se, 
          ci_u = mean + qt(0.975, n_weight)*se
          
          
        ) %>%
        rename_with(
          .fn = function(x) by_split,
          .cols = contains("eval(parse")
        )
    }else{
      data = data %>% 
        filter(!is.na(eval(parse(text=outcome)))) %>% 
        group_by(eval(parse(text=by))) %>% 
        summarise(
          mean = weighted.mean(x = eval(parse(text=outcome)),
                               w = eval(parse(text=survey_weight)),
                               na.rm = T),
          n_raw = sum(!is.na(eval(parse(text=outcome)))),
          n_weight = sum(eval(parse(text=survey_weight))),
          se = return_se_wgt(eval(parse(text=survey_weight)),
                             eval(parse(text=outcome)),
                             mean),
          ci_l = mean - qt(0.975, n_weight)*se, 
          ci_u = mean + qt(0.975, n_weight)*se
        ) %>% 
        rename(by_var = `eval(parse(text = by))`)
      colnames(data)[colnames(data) == "by_var"] = by
      return(data)
    }
  }
  
}

return_se = function(choice_n, total_n, weight = "NULL"){
  if(weight == "NULL"){
    se_vec = as.numeric()
    for(i in 1:length(choice_n)){
      vec = c(rep(1, choice_n[i]), rep(0, total_n[i] - choice_n[i]))
      se = sqrt(var(vec))
      se_vec[i] = se
    }
  }else{
    
  }
  return(se_vec)
}

return_se_wgt = function(weights, values, wmean){
  sum_error_wtd = sum(
    weights * (values - wmean)^2
  ) / (sum(weights) - 1)
  
  se_wgt = sqrt(sum_error_wtd) / sqrt(sum(weights))
  return(se_wgt)
}
